﻿using PARK.Common.Core.Manager;
using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PARK.Accessctl.Entitys;
using Yitter.IdGenerator;
using PARK.Common.Helper;
using PARK.JsonSerialization;
using PARK.System.Entitys.Permission;
using PARK.System.Interfaces.Permission;
using PARK.Common.Util;
using PARK.CardAcct.Entitys;
using System.Text;
using PARK.Attend.Interfaces.AttendCmdModel;
using PARK.Attend.Entitys;
using PARK.Attend.Entitys.Dto.AttendMachs;

namespace PARK.Attend.AttendCmdModel
{
    /// <summary>
    /// 权限管理服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Attend", Name = "AttendCmdModel", Order = 200)]
    [Route("api/Attend/[controller]")]
    public class AttendCmdModelService : IAttendCmdModelService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<AttendCmdModelEntity> _attendCmdModelRepository;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;
        private readonly IOrganizeService _organizeService; // 机构表仓储

        /// <summary>
        /// 初始化一个<see cref="AttendCmdModelService"/>类型的新实例
        /// </summary>
        public AttendCmdModelService(
            ISqlSugarRepository<AttendCmdModelEntity> attendCmdModelRepository,
            IUserManager userManager,
            IOrganizeService organizeService)
        {
            _attendCmdModelRepository = attendCmdModelRepository;
            _db = _attendCmdModelRepository.Context;
            _userManager = userManager;
            _organizeService = organizeService;
        }

        #region Get
        /// <summary>
        /// 获取权限管理
        /// </summary>
        /// <param name="id">参数</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<dynamic> GetInfo(string id)
        {
            var entity = await _db.Queryable<AttendCmdModelEntity>().FirstAsync(p => p.Id == id);
            var output = entity.Adapt<AttendCmdModelInfoOutput>();
            return output;
        }
        /// <summary>
		/// 获取权限管理列表
		/// </summary>
		/// <param name="input">请求参数</param>
		/// <returns></returns>
        [HttpGet("")]
        public async Task<dynamic> GetList([FromQuery] AttendCmdModelListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "Id" : input.sidx;
            var organizeIds = new List<string>();
            if (!input.organizeId.IsNullOrEmpty())
                organizeIds = await GetSubOrganizeIds(input.organizeId);
            //最后下发日期
            List<string> queryBillDate = input.commitTime != null ? input.commitTime.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
            DateTime? endBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
            var data = await _db.Queryable<AttendCmdModelEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId))//权限
                //关键字查询
                .WhereIF(!input.keyword.IsNullOrEmpty(), p => p.DevSN.Contains(input.keyword) || p.CardNo.Contains(input.keyword) || p.JobNo.Contains(input.keyword) || p.ReallName.Contains(input.keyword))
                //组织机构
                .WhereIF(organizeIds.Any(), u => organizeIds.Contains(SqlFunc.ToString(u.DepartId)))
                .WhereIF(!string.IsNullOrEmpty(input.devSN), p => p.DevSN.Contains(input.devSN))
                //下发日期查询
                .WhereIF(queryBillDate != null, a => a.CommitTime >= new DateTime(startBilldate.ToDate().Year, startBilldate.ToDate().Month, startBilldate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, a => a.CommitTime <= new DateTime(endBilldate.ToDate().Year, endBilldate.ToDate().Month, endBilldate.ToDate().Day, 23, 59, 59))
                .Select(it => new AttendCmdModelListOutput
                {
                    id = it.Id,
                    machlId = it.machlId,
                    machName = it.machName,
                    devSN = it.DevSN,
                    doorAreaId = it.doorAreaId,
                    doorAreaName = it.doorAreaName,
                    ctlposition = it.ctlposition,
                    employeeId = it.EmployeeId,
                    jobNo = it.JobNo,
                    reallName = it.ReallName,
                    departId = it.DepartId,
                    departName = it.DepartName,
                    cardNo = it.CardNo,
                    addorDel = it.AddorDel,
                    cmdContent = it.CmdContent,
                    commitTime = it.CommitTime,
                    transTime = it.TransTime,
                    responseTime = it.ResponseTime,
                    returnValue = it.ReturnValue,
                    creatorUserId = it.CreatorUserId,
                    creatorTime = it.CreatorTime,
                    creatorUserName = it.CreatorUserName,
                    taskStatus = it.taskStatus
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<AttendCmdModelListOutput>.SqlSugarPageResult(data);
        }

        /// <summary>
        /// 下属机构
        /// </summary>
        /// <param name="organizeId">机构ID</param>
        /// <returns></returns>
        [NonAction]
        public async Task<List<string>> GetSubOrganizeIds(string organizeId)
        {
            var data = await _organizeService.GetListAsync();
            data = data.TreeChildNode(organizeId, t => t.Id, t => t.ParentId);
            return data.Select(m => m.Id).ToList();
        }
        #endregion

        #region 批量下发考勤名单任务
        /// <summary>
        /// 批量下发考勤名单任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("AttendCmdmodelBatchAdd")]
        public async Task AttendCmdmodelBatchAdd([FromBody] AttendCmdModelCrBatchInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            try
            {
                if (input.machList == null || input.machList.Count == 0)
                {
                    throw PARKException.Bah("请选择考勤机");
                }
                if (input.eyeList == null || input.eyeList.Count == 0)
                {
                    throw PARKException.Bah("请选择人员");
                }
                List<AttendCmdModelEntity> authTaskList = new List<AttendCmdModelEntity>();
                var _machList = input.machList;
                var _eyeList = input.eyeList;
                foreach (var item in _machList)
                {
                    foreach (var eye in _eyeList)
                    {
                        var Entity = new AttendCmdModelEntity();
                        if (input.ctlpass == 1)
                        {
                            Entity.AddorDel = 1;
                            Entity.CmdContent = string.Format(AttendCommands.Command_UpdateUserInfo, eye.jobNo, eye.reallName, "0", "", eye.cardNo, "0", "0"); //下发命令内容
                        }
                        else
                        {
                            Entity.AddorDel = 2;
                            Entity.CmdContent = string.Format(AttendCommands.Command_DeleteUser, eye.jobNo); //下发命令内容
                        }
                        Entity.CommitTime = DateTime.Now;
                        Entity.Create();
                        //考勤机
                        Entity.machlId = item.machlId;
                        Entity.machName = item.machName;
                        Entity.DevSN = item.machSN;
                        Entity.doorAreaId = item.doorAreaId;
                        Entity.doorAreaName = item.doorAreaName;
                        Entity.ctlposition = item.ctlposition;
                        //人员
                        Entity.EmployeeId = eye.employeeId;
                        Entity.JobNo = eye.jobNo;
                        Entity.ReallName = eye.reallName;
                        Entity.CardNo = eye.cardNo;
                        Entity.DepartId = eye.departId;
                        Entity.DepartName = eye.departName;
                        Entity.CompanyId = userInfo.companyId;
                        Entity.CompanyName = userInfo.companyName;
                        Entity.IsDeleteTask = Entity.AddorDel == 2 ? 1 : 0;
                        authTaskList.Add(Entity);
                    }
                }
                if (authTaskList != null && authTaskList.Count > 0)
                {
                    var isOk = await _db.Insertable(authTaskList).ExecuteCommandAsync();
                    if (!(isOk > 0)) throw PARKException.Oh(ErrorCode.COM1000);
                }
            }
            catch (Exception ex)
            {
                throw PARKException.Oh(ex.Message);
            }
        }
        #endregion

        #region 下发单个人考勤名单任务
        /// <summary>
        /// 下发单个人考勤名单任务
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("AttendCmdModelAdd")]
        public async Task AttendCmdModelAdd([FromBody] AttendCmdModelCrSingeInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            try
            {
                if (string.IsNullOrEmpty(input.EmployeeId))
                {
                    throw PARKException.Bah("请选择人员");
                }
                var EyeEntity = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == input.EmployeeId);
                List<AttendCmdModelEntity> authTaskList = new List<AttendCmdModelEntity>();
                if (input.machList != null)
                {
                    string _addMachIds = "";
                    if (input.machList.Count > 0)
                    {
                        foreach (var item in input.machList)
                        {
                            if (!string.IsNullOrEmpty(item))
                            {
                                _addMachIds += "'" + item + "',";
                            }
                        }
                        _addMachIds = _addMachIds.Length > 0 ? _addMachIds.Substring(0, _addMachIds.Length - 1) : "";

                        #region 处理需要添加权限
                        if (_addMachIds.Length > 0)
                        {
                            StringBuilder _dbSql = new StringBuilder("select a.machlId,a.machSN,a.machName,a.doorAreaId,a.doorAreaName,a.ctlposition ");
                            _dbSql.Append(" from attend_machs a where a.EnabledMark=1 and a.IsDeleted=0 ");
                            _dbSql.AppendFormat(" and a.CompanyId ='{0}'", userInfo.companyId);
                            _dbSql.AppendFormat(" and a.machlId in ({0})", _addMachIds);
                            _dbSql.Append(" order by a.machSN asc");

                            var _AttendMachsList = await _db.SqlQueryable<AttendMachsListOutput>(_dbSql.ToString()).ToListAsync();
                            if (_AttendMachsList != null && _AttendMachsList.Count > 0)
                            {
                                foreach (var item in _AttendMachsList)
                                {
                                    if (item != null)
                                    {
                                        var Entity = new AttendCmdModelEntity();
                                        Entity.AddorDel = 1;
                                        Entity.CmdContent = string.Format(AttendCommands.Command_UpdateUserInfo, EyeEntity.JobNum, EyeEntity.RealName, "0", "", EyeEntity.CardNo, "0", "0"); //下发命令内容
                                        Entity.CommitTime = DateTime.Now;
                                        Entity.Create();
                                        //考勤机
                                        Entity.machlId = item.machlId;
                                        Entity.machName = item.machName;
                                        Entity.DevSN = item.machSN;
                                        Entity.doorAreaId = item.doorAreaId;
                                        Entity.doorAreaName = item.doorAreaName;
                                        Entity.ctlposition = item.ctlposition;
                                        //人员
                                        Entity.EmployeeId = EyeEntity.EmployeeId;
                                        Entity.JobNo = EyeEntity.JobNum;
                                        Entity.ReallName = EyeEntity.RealName;
                                        Entity.CardNo = EyeEntity.CardNo;
                                        Entity.DepartId = EyeEntity.DepartId;
                                        Entity.DepartName = EyeEntity.DepartName;
                                        Entity.CompanyId = userInfo.companyId;
                                        Entity.CompanyName = userInfo.companyName;
                                        Entity.IsDeleteTask = 0;
                                        authTaskList.Add(Entity);
                                    }
                                }
                            }
                        }
                        #endregion
                    }

                    #region 处理需删除权限
                    if (string.IsNullOrEmpty(_addMachIds))
                        _addMachIds = "''";
                    StringBuilder dbSql = new StringBuilder("select a.machlId,a.machSN,a.machName,a.doorAreaId,a.doorAreaName,a.ctlposition ");
                    dbSql.Append(" from attend_machs a ");
                    dbSql.AppendFormat(" where a.machlId not in ({0})", _addMachIds);
                    dbSql.AppendFormat(" and a.CompanyId ='{0}'", userInfo.companyId);
                    dbSql.Append(" order by a.machSN asc");
                    var data = await _db.SqlQueryable<AttendMachsListOutput>(dbSql.ToString()).ToListAsync();
                    foreach (var item in data)
                    {
                        if (item != null)
                        {
                            var Entity = new AttendCmdModelEntity();
                            Entity.AddorDel = 2;
                            Entity.CmdContent = string.Format(AttendCommands.Command_DeleteUser, EyeEntity.JobNum); //下发命令内容
                            Entity.CommitTime = DateTime.Now;
                            Entity.Create();
                            //考勤机
                            Entity.machlId = item.machlId;
                            Entity.machName = item.machName;
                            Entity.DevSN = item.machSN;
                            Entity.doorAreaId = item.doorAreaId;
                            Entity.doorAreaName = item.doorAreaName;
                            Entity.ctlposition = item.ctlposition;
                            //人员
                            Entity.EmployeeId = EyeEntity.EmployeeId;
                            Entity.JobNo = EyeEntity.JobNum;
                            Entity.ReallName = EyeEntity.RealName;
                            Entity.CardNo = EyeEntity.CardNo;
                            Entity.DepartId = EyeEntity.DepartId;
                            Entity.DepartName = EyeEntity.DepartName;
                            Entity.CompanyId = userInfo.companyId;
                            Entity.CompanyName = userInfo.companyName;
                            Entity.IsDeleteTask = 1;
                            authTaskList.Add(Entity);
                        }
                    }
                    #endregion
                }

                if (authTaskList != null && authTaskList.Count > 0)
                {
                    var isOk = await _db.Insertable(authTaskList).ExecuteCommandAsync();
                    if (!(isOk > 0)) throw PARKException.Oh(ErrorCode.COM1000);
                }
            }
            catch (Exception ex)
            {
                throw PARKException.Oh(ex.Message);
            }
        }
        #endregion

        /// <summary>
        /// 删除权限管理
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task Delete(string id)
        {
            var entity = await _db.Queryable<AttendCmdModelEntity>().FirstAsync(p => p.Id == id);
            _ = entity ?? throw PARKException.Oh(ErrorCode.COM1005);
            var isOk = await _db.Deleteable<AttendCmdModelEntity>().Where(d => d.Id == id).ExecuteCommandAsync();
            if (!(isOk > 0)) throw PARKException.Oh(ErrorCode.COM1002);
        }
    }
}
